<!DOCTYPE html>
<html id="docs" lang="en" class="">
	<head>
	<meta charset="utf-8">
<title>Containers - Kubernetes</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="../../../images/favicon.png">
<link rel="stylesheet" type="text/css" href="../../../css/base_fonts.css">
<link rel="stylesheet" type="text/css" href="../../../css/styles.css">
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css">
<link rel="stylesheet" type="text/css" href="../../../css/callouts.css">
<link rel="stylesheet" type="text/css" href="../../../css/custom-jekyll/tags.css">




<meta name="description" content="Containers" />
<meta property="og:description" content="Containers" />

<meta property="og:url" content="https://kubernetes.io/docs/concepts/containers/" />
<meta property="og:title" content="Containers - Kubernetes" />

<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script
src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<script src="../../../js/script.js"></script>
<script src="../../../js/custom-jekyll/tags.js"></script>


	</head>
	<body>
		<div id="cellophane" onclick="kub.toggleMenu()"></div>

<header>
    <a href="../../../index.html" class="logo"></a>

    <div class="nav-buttons" data-auto-burger="primary">
        <ul class="global-nav">
            
            
            <li><a href="../../home.1">Documentation</a></li>
            
            <li><a href="../../../blog/index.html">Blog</a></li>
            
            <li><a href="../../../partners/index.html">Partners</a></li>
            
            <li><a href="../../../community/index.html">Community</a></li>
            
            <li><a href="../../../case-studies/index.html">Case Studies</a></li>
            
            
             <li>
                <a href="index.html#">
                    English <span class="ui-icon ui-icon-carat-1-s"></span>
                </a>
                <ul>
                
                    <li><a href="../../../zh/index.html">中文 Chinese</a></li>
                
                    <li><a href="../../../ko/index.html">한국어 Korean</a></li>
                
                </ul>
            </li>
         
            <li>
                <a href="index.html#">
                    v1.11 <span class="ui-icon ui-icon-carat-1-s"></span>
                </a>
                <ul>
                
                    <li><a href="https://kubernetes.io">v1.12</a></li>
                
                    <li><a href="../../../index.html">v1.11</a></li>
                
                    <li><a href="https://v1-10.docs.kubernetes.io">v1.10</a></li>
                
                    <li><a href="https://v1-9.docs.kubernetes.io">v1.9</a></li>
                
                </ul>
            </li>
        </ul>
        
        <a href="../../tutorials/kubernetes-basics/index.html" class="button" id="tryKubernetes" data-auto-burger-exclude>Try Kubernetes</a>
        <button id="hamburger" onclick="kub.toggleMenu()" data-auto-burger-exclude><div></div></button>
    </div>

    <nav id="mainNav">
        <main data-auto-burger="primary">
        <div class="nav-box">
            <h3><a href="../../tutorials/stateless-application/hello-minikube/index.html">Get Started</a></h3>
            <p>Ready to get your hands dirty? Build a simple Kubernetes cluster that runs "Hello World" for Node.js.</p>
        </div>
        <div class="nav-box">
            <h3><a href="../../home.1">Documentation</a></h3>
            <p>Learn how to use Kubernetes with the use of walkthroughs, samples, and reference documentation. You can even <a href="../../../editdocs/index.html" data-auto-burger-exclude>help contribute to the docs</a>!</p>
        </div>
        <div class="nav-box">
            <h3><a href="../../../community/index.html">Community</a></h3>
            <p>If you need help, you can connect with other Kubernetes users and the Kubernetes authors, attend community events, and watch video presentations from around the web.</p>
        </div>
        <div class="nav-box">
            <h3><a href="../../../blog/index.html">Blog</a></h3>
            <p>Read the latest news for Kubernetes and the containers space in general, and get technical how-tos hot off the presses.</p>
        </div>
        </main>
        <main data-auto-burger="primary">
        <div class="left">
            <h5 class="github-invite">Interested in hacking on the core Kubernetes code base?</h5>
            <a href="https://github.com/kubernetes/kubernetes" class="button" data-auto-burger-exclude>View On Github</a>
        </div>

        <div class="right">
            <h5 class="github-invite">Explore the community</h5>
            <div class="social">
                <a href="https://twitter.com/kubernetesio" class="twitter"><span>Twitter</span></a>
                <a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
                <a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
                <a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>Stack Overflow</span></a>
                <a href="https://discuss.kubernetes.io" class="mailing-list"><span>Forum</span></a>
                <a href="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com" class="calendar"><span>Events Calendar</span></a>
            </div>
        </div>
        <div class="clear" style="clear: both"></div>
        </main>
    </nav>
</header>

		
		
		<section id="hero" class="light-text no-sub">
			









<h1>Concepts</h1>
<h5></h5>








<div id="vendorStrip" class="light-text">
	<ul>
		
		
		<li><a href="../../home.1">DOCUMENTATION</a></li>
		
		
		<li><a href="../../setup/index.html">SETUP</a></li>
		
		
		<li><a href="../index.html" class="YAH">CONCEPTS</a></li>
		
		
		<li><a href="../../tasks/index.html">TASKS</a></li>
		
		
		<li><a href="../../tutorials/index.html">TUTORIALS</a></li>
		
		
		<li><a href="../../reference.1">REFERENCE</a></li>
		
	</ul>
	<div id="searchBox">
		<input type="text" id="search" placeholder="Search" onkeydown="if (event.keyCode==13) window.location.replace('/docs/search/?q=' + this.value)" autofocus="autofocus">
	</div>
</div>

		</section>
		
		
<section id="deprecationWarning">
  <main>
    <div class="content deprecation-warning">
      <h3>
        Documentation for Kubernetes v1.11 is no longer actively maintained. The version you are currently viewing is a static snapshot.
        For up-to-date documentation, see the <a href="https://kubernetes.io/docs/home/">latest</a> version.
      </h3>
    </div>
  </main>
</section>


		<section id="encyclopedia">
			
<div id="docsToc">
     <div class="pi-accordion">
    	
        
        
        
        
        
         
             
                 
             
         
             
                 
             
         
             
                 
                          
                          
                 
             
         
             
         
             
         
             
         
             
         
             
         
         
        
        <a class="item" data-title="Concepts" href="../index.html"></a>

	
	
		
		
	<div class="item" data-title="Overview">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="What is Kubernetes?" href="../overview/index.html"></a>

		
	
		
		
<a class="item" data-title="Kubernetes Components" href="../overview/components.1"></a>

		
	
		
		
<a class="item" data-title="The Kubernetes API" href="../overview/kubernetes-api/index.html"></a>

		
	
		
		
	<div class="item" data-title="Working with Kubernetes Objects">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Understanding Kubernetes Objects" href="../overview/working-with-objects/kubernetes-objects.1"></a>

		
	
		
		
<a class="item" data-title="Names" href="../../user-guide/identifiers"></a>

		
	
		
		
<a class="item" data-title="Namespaces" href="../overview/working-with-objects/namespaces.1"></a>

		
	
		
		
<a class="item" data-title="Labels and Selectors" href="../../user-guide/labels"></a>

		
	
		
		
<a class="item" data-title="Annotations" href="../overview/working-with-objects/annotations.1"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Object Management Using kubectl">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Kubernetes Object Management" href="../../tutorials/object-management-kubectl/object-management/index.html"></a>

		
	
		
		
<a class="item" data-title="Managing Kubernetes Objects Using Imperative Commands" href="../../tutorials/object-management-kubectl/imperative-object-management-command/index.html"></a>

		
	
		
		
<a class="item" data-title="Imperative Management of Kubernetes Objects Using Configuration Files" href="../../tutorials/object-management-kubectl/imperative-object-management-configuration/index.html"></a>

		
	
		
		
<a class="item" data-title="Declarative Management of Kubernetes Objects Using Configuration Files" href="../../tutorials/object-management-kubectl/declarative-object-management-configuration/index.html"></a>

		
	

		</div>
	</div>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Compute, Storage, and Networking Extensions">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Cluster Administration Overview" href="../cluster-administration/cluster-administration-overview/index.html"></a>

		
	
		
		
<a class="item" data-title="Certificates" href="../cluster-administration/certificates/index.html"></a>

		
	
		
		
<a class="item" data-title="Cloud Providers" href="../cluster-administration/cloud-providers/index.html"></a>

		
	
		
		
<a class="item" data-title="Managing Resources" href="../cluster-administration/manage-deployment/index.html"></a>

		
	
		
		
<a class="item" data-title="Cluster Networking" href="../../admin/networking"></a>

		
	
		
		
<a class="item" data-title="Logging Architecture" href="../cluster-administration/logging.1"></a>

		
	
		
		
<a class="item" data-title="Configuring kubelet Garbage Collection" href="../cluster-administration/kubelet-garbage-collection/index.html"></a>

		
	
		
		
<a class="item" data-title="Federation" href="../cluster-administration/federation/index.html"></a>

		
	
		
		
<a class="item" data-title="Proxies in Kubernetes" href="../cluster-administration/proxies/index.html"></a>

		
	
		
		
<a class="item" data-title="Controller manager metrics" href="../cluster-administration/controller-metrics/index.html"></a>

		
	
		
		
<a class="item" data-title="Installing Addons" href="../cluster-administration/addons/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Kubernetes Architecture">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Nodes" href="../../admin/node.1"></a>

		
	
		
		
<a class="item" data-title="Master-Node communication" href="../architecture/master-node-communication/index.html"></a>

		
	
		
		
<a class="item" data-title="Concepts Underlying the Cloud Controller Manager" href="../architecture/cloud-controller/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Extending Kubernetes">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Extending your Kubernetes Cluster" href="../overview/extending/index.html"></a>

		
	
		
		
	<div class="item" data-title="Extending the Kubernetes API">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Extending the Kubernetes API with the aggregation layer" href="../api-extension/apiserver-aggregation.1"></a>

		
	
		
		
<a class="item" data-title="Custom Resources" href="../api-extension/custom-resources/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Compute, Storage, and Networking Extensions">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Network Plugins" href="../../admin/network-plugins/index.html"></a>

		
	
		
		
<a class="item" data-title="Device Plugins" href="../cluster-administration/device-plugins.1"></a>

		
	

		</div>
	</div>

		
	
		
		
<a class="item" data-title="Service Catalog" href="../service-catalog/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Containers">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Images" href="images/index.html"></a>

		
	
		
		
<a class="item" data-title="Container Environment Variables" href="container-environment-variables/index.html"></a>

		
	
		
		
<a class="item" data-title="Container Lifecycle Hooks" href="container-lifecycle-hooks/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Workloads">
		<div class="container">
		
		
	
	
		
		
	<div class="item" data-title="Pods">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Pod Overview" href="../workloads/pods/pod-overview/index.html"></a>

		
	
		
		
<a class="item" data-title="Pods" href="../../user-guide/pods/index.html"></a>

		
	
		
		
<a class="item" data-title="Pod Lifecycle" href="../../user-guide/pod-states/index.html"></a>

		
	
		
		
<a class="item" data-title="Init Containers" href="../abstractions/init-containers/index.html"></a>

		
	
		
		
<a class="item" data-title="Pod Preset" href="../workloads/pods/podpreset/index.html"></a>

		
	
		
		
<a class="item" data-title="Disruptions" href="../workloads/pods/disruptions/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Controllers">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="ReplicaSet" href="../workloads/controllers/replicaset/index.html"></a>

		
	
		
		
<a class="item" data-title="ReplicationController" href="../../user-guide/replication-controller/index.html"></a>

		
	
		
		
<a class="item" data-title="Deployments" href="../workloads/controllers/deployment/index.html"></a>

		
	
		
		
<a class="item" data-title="StatefulSets" href="../workloads/controllers/statefulset.md"></a>

		
	
		
		
<a class="item" data-title="DaemonSet" href="../workloads/controllers/daemonset.1"></a>

		
	
		
		
<a class="item" data-title="Garbage Collection" href="../workloads/controllers/garbage-collection/index.html"></a>

		
	
		
		
<a class="item" data-title="Jobs - Run to Completion" href="../workloads/controllers/jobs-run-to-completion.1"></a>

		
	
		
		
<a class="item" data-title="CronJob" href="../workloads/controllers/cron-jobs.1"></a>

		
	

		</div>
	</div>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Configuration">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Configuration Best Practices" href="../configuration/overview/index.html"></a>

		
	
		
		
<a class="item" data-title="Managing Compute Resources for Containers" href="../../user-guide/compute-resources/index.html"></a>

		
	
		
		
<a class="item" data-title="Assigning Pods to Nodes" href="../../user-guide/node-selection/index.html"></a>

		
	
		
		
<a class="item" data-title="Taints and Tolerations" href="../configuration/taint-and-toleration.1"></a>

		
	
		
		
<a class="item" data-title="Secrets" href="../../user-guide/secrets.1"></a>

		
	
		
		
<a class="item" data-title="Organizing Cluster Access Using kubeconfig Files" href="../configuration/organize-cluster-access-kubeconfig/index.html"></a>

		
	
		
		
<a class="item" data-title="Pod Priority and Preemption" href="../configuration/pod-priority-preemption/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Services, Load Balancing, and Networking">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Services" href="../../user-guide/services"></a>

		
	
		
		
<a class="item" data-title="DNS for Services and Pods" href="../services-networking/dns-pod-service/index.html"></a>

		
	
		
		
<a class="item" data-title="Connecting Applications with Services" href="../services-networking/connect-applications-service.1"></a>

		
	
		
		
<a class="item" data-title="Ingress" href="../services-networking/ingress/index.html"></a>

		
	
		
		
<a class="item" data-title="Network Policies" href="../services-networking/networkpolicies/index.html"></a>

		
	
		
		
<a class="item" data-title="Adding entries to Pod /etc/hosts with HostAliases" href="../services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Storage">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Volumes" href="../storage/volumes.1"></a>

		
	
		
		
<a class="item" data-title="Persistent Volumes" href="../../user-guide/persistent-volumes/index.html"></a>

		
	
		
		
<a class="item" data-title="Storage Classes" href="../storage/storage-classes.1"></a>

		
	
		
		
<a class="item" data-title="Dynamic Volume Provisioning" href="../storage/dynamic-provisioning/index.html"></a>

		
	
		
		
<a class="item" data-title="Node-specific Volume Limits" href="../storage/storage-limits/index.html"></a>

		
	

		</div>
	</div>

		
	
		
		
	<div class="item" data-title="Policies">
		<div class="container">
		
		
	
	
		
		
<a class="item" data-title="Resource Quotas" href="../policy/resource-quotas/index.html"></a>

		
	
		
		
<a class="item" data-title="Pod Security Policies" href="../../user-guide/pod-security-policy"></a>

		
	

		</div>
	</div>

		
	






     </div> 
    <button class="push-menu-close-button" onclick="kub.toggleToc()"></button>
</div> 

			<div id="docsContent">
				
	 
    
    
    <p><a href="../../editdocs#docs/concepts/containers/images.md" id="editPageButton">Edit This Page</a></p>

<h1>Images</h1>



<p>You create your Docker image and push it to a registry before referring to it in a Kubernetes pod.</p>

<p>The <code>image</code> property of a container supports the same syntax as the <code>docker</code> command does, including private registries and tags.</p>









<ul id="markdown-toc">










<li><a href="index.html#updating-images">Updating Images</a></li>




<li><a href="index.html#using-a-private-registry">Using a Private Registry</a></li>



















</ul>


<h2 id="updating-images">Updating Images</h2>

<p>The default pull policy is <code>IfNotPresent</code> which causes the Kubelet to skip
pulling an image if it already exists. If you would like to always force a pull,
you can do one of the following:</p>

<ul>
<li>set the <code>imagePullPolicy</code> of the container to <code>Always</code>;</li>
<li>use <code>:latest</code> as the tag for the image to use;</li>
<li>enable the <a href="../../admin/admission-controllers/index.html#alwayspullimages">AlwaysPullImages</a> admission controller.</li>
</ul>

<p>If you did not specify tag of your image, it will be assumed as <code>:latest</code>, with
pull image policy of <code>Always</code> correspondingly.</p>

<p>Note that you should avoid using <code>:latest</code> tag, see <a href="../configuration/overview/index.html#container-images">Best Practices for Configuration</a> for more information.</p>

<h2 id="using-a-private-registry">Using a Private Registry</h2>

<p>Private registries may require keys to read images from them.
Credentials can be provided in several ways:</p>

<ul>
<li>Using Google Container Registry

<ul>
<li>Per-cluster</li>
<li>automatically configured on Google Compute Engine or Google Kubernetes Engine</li>
<li>all pods can read the project&rsquo;s private registry</li>
</ul></li>
<li>Using AWS EC2 Container Registry (ECR)

<ul>
<li>use IAM roles and policies to control access to ECR repositories</li>
<li>automatically refreshes ECR login credentials</li>
</ul></li>
<li>Using Azure Container Registry (ACR)</li>
<li>Configuring Nodes to Authenticate to a Private Registry

<ul>
<li>all pods can read any configured private registries</li>
<li>requires node configuration by cluster administrator</li>
</ul></li>
<li>Pre-pulling Images

<ul>
<li>all pods can use any images cached on a node</li>
<li>requires root access to all nodes to setup</li>
</ul></li>
<li>Specifying ImagePullSecrets on a Pod

<ul>
<li>only pods which provide own keys can access the private registry
Each option is described in more detail below.</li>
</ul></li>
</ul>

<h3 id="using-google-container-registry">Using Google Container Registry</h3>

<p>Kubernetes has native support for the <a href="https://cloud.google.com/tools/container-registry/" target="_blank">Google Container
Registry (GCR)</a>, when running on Google Compute
Engine (GCE).  If you are running your cluster on GCE or Google Kubernetes Engine, simply
use the full image name (e.g. gcr.io/my_project/image:tag).</p>

<p>All pods in a cluster will have read access to images in this registry.</p>

<p>The kubelet will authenticate to GCR using the instance&rsquo;s
Google service account.  The service account on the instance
will have a <code>https://www.googleapis.com/auth/devstorage.read_only</code>,
so it can pull from the project&rsquo;s GCR, but not push.</p>

<h3 id="using-aws-ec2-container-registry">Using AWS EC2 Container Registry</h3>

<p>Kubernetes has native support for the <a href="https://aws.amazon.com/ecr/" target="_blank">AWS EC2 Container
Registry</a>, when nodes are AWS EC2 instances.</p>

<p>Simply use the full image name (e.g. <code>ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag</code>)
in the Pod definition.</p>

<p>All users of the cluster who can create pods will be able to run pods that use any of the
images in the ECR registry.</p>

<p>The kubelet will fetch and periodically refresh ECR credentials.  It needs the following permissions to do this:</p>

<ul>
<li><code>ecr:GetAuthorizationToken</code></li>
<li><code>ecr:BatchCheckLayerAvailability</code></li>
<li><code>ecr:GetDownloadUrlForLayer</code></li>
<li><code>ecr:GetRepositoryPolicy</code></li>
<li><code>ecr:DescribeRepositories</code></li>
<li><code>ecr:ListImages</code></li>
<li><code>ecr:BatchGetImage</code></li>
</ul>

<p>Requirements:</p>

<ul>
<li>You must be using kubelet version <code>v1.2.0</code> or newer.  (e.g. run <code>/usr/bin/kubelet --version=true</code>).</li>
<li>If your nodes are in region A and your registry is in a different region B, you need version <code>v1.3.0</code> or newer.</li>
<li>ECR must be offered in your region</li>
</ul>

<p>Troubleshooting:</p>

<ul>
<li>Verify all requirements above.</li>
<li>Get $REGION (e.g. <code>us-west-2</code>) credentials on your workstation. SSH into the host and run Docker manually with those creds. Does it work?</li>
<li>Verify kubelet is running with <code>--cloud-provider=aws</code>.</li>
<li>Check kubelet logs (e.g. <code>journalctl -u kubelet</code>) for log lines like:

<ul>
<li><code>plugins.go:56] Registering credential provider: aws-ecr-key</code></li>
<li><code>provider.go:91] Refreshing cache for provider: *aws_credentials.ecrProvider</code></li>
</ul></li>
</ul>

<h3 id="using-azure-container-registry-acr">Using Azure Container Registry (ACR)</h3>

<p>When using <a href="https://azure.microsoft.com/en-us/services/container-registry/" target="_blank">Azure Container Registry</a>
you can authenticate using either an admin user or a service principal.
In either case, authentication is done via standard Docker authentication.  These instructions assume the
<a href="https://github.com/azure/azure-cli" target="_blank">azure-cli</a> command line tool.</p>

<p>You first need to create a registry and generate credentials, complete documentation for this can be found in
the <a href="https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-azure-cli" target="_blank">Azure container registry documentation</a>.</p>

<p>Once you have created your container registry, you will use the following credentials to login:</p>

<ul>
<li><code>DOCKER_USER</code> : service principal, or admin username</li>
<li><code>DOCKER_PASSWORD</code>: service principal password, or admin user password</li>
<li><code>DOCKER_REGISTRY_SERVER</code>: <code>${some-registry-name}.azurecr.io</code></li>
<li><code>DOCKER_EMAIL</code>: <code>${some-email-address}</code></li>
</ul>

<p>Once you have those variables filled in you can
<a href="images/index.html#specifying-imagepullsecrets-on-a-pod">configure a Kubernetes Secret and use it to deploy a Pod</a>.</p>

<h3 id="configuring-nodes-to-authenticate-to-a-private-repository">Configuring Nodes to Authenticate to a Private Repository</h3>

<p><strong>Note:</strong> if you are running on Google Kubernetes Engine, there will already be a <code>.dockercfg</code> on each node with credentials for Google Container Registry.  You cannot use this approach.</p>

<p><strong>Note:</strong> if you are running on AWS EC2 and are using the EC2 Container Registry (ECR), the kubelet on each node will
manage and update the ECR login credentials. You cannot use this approach.</p>

<p><strong>Note:</strong> this approach is suitable if you can control node configuration.  It
will not work reliably on GCE, and any other cloud provider that does automatic
node replacement.</p>

<p>Docker stores keys for private registries in the <code>$HOME/.dockercfg</code> or <code>$HOME/.docker/config.json</code> file.  If you put this
in the <code>$HOME</code> of user <code>root</code> on a kubelet, then docker will use it.</p>

<p>Here are the recommended steps to configuring your nodes to use a private registry.  In this
example, run these on your desktop/laptop:</p>

<ol>
<li>Run <code>docker login [server]</code> for each set of credentials you want to use.  This updates <code>$HOME/.docker/config.json</code>.</li>
<li>View <code>$HOME/.docker/config.json</code> in an editor to ensure it contains just the credentials you want to use.</li>
<li>Get a list of your nodes, for example:

<ul>
<li>if you want the names: <code>nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')</code></li>
<li>if you want to get the IPs: <code>nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type==&quot;ExternalIP&quot;)]}{.address} {end}')</code></li>
</ul></li>
<li>Copy your local <code>.docker/config.json</code> to the home directory of root on each node.

<ul>
<li>for example: <code>for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done</code></li>
</ul></li>
</ol>

<p>Verify by creating a pod that uses a private image, e.g.:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">$<span style="color:#bbb"> </span>cat<span style="color:#bbb"> </span>&lt;&lt;EOF<span style="color:#bbb"> </span><span style="color:#b44;font-style:italic">&gt; /tmp/private-image-test-1.yaml</span><span style="color:#bbb">
</span><span style="color:#bbb"></span>apiVersion:<span style="color:#bbb"> </span>v1<span style="color:#bbb">
</span><span style="color:#bbb"></span>kind:<span style="color:#bbb"> </span>Pod<span style="color:#bbb">
</span><span style="color:#bbb"></span>metadata:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>name:<span style="color:#bbb"> </span>private-image-test-<span style="color:#666">1</span><span style="color:#bbb">
</span><span style="color:#bbb"></span>spec:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>containers:<span style="color:#bbb">
</span><span style="color:#bbb">    </span>-<span style="color:#bbb"> </span>name:<span style="color:#bbb"> </span>uses-private-image<span style="color:#bbb">
</span><span style="color:#bbb">      </span>image:<span style="color:#bbb"> </span>$PRIVATE_IMAGE_NAME<span style="color:#bbb">
</span><span style="color:#bbb">      </span>imagePullPolicy:<span style="color:#bbb"> </span>Always<span style="color:#bbb">
</span><span style="color:#bbb">      </span>command:<span style="color:#bbb"> </span>[<span style="color:#bbb"> </span><span style="color:#b44">&#34;echo&#34;</span>,<span style="color:#bbb"> </span><span style="color:#b44">&#34;SUCCESS&#34;</span><span style="color:#bbb"> </span>]<span style="color:#bbb">
</span><span style="color:#bbb"></span>EOF<span style="color:#bbb">
</span><span style="color:#bbb"></span>$<span style="color:#bbb"> </span>kubectl<span style="color:#bbb"> </span>create<span style="color:#bbb"> </span>-f<span style="color:#bbb"> </span>/tmp/private-image-test-<span style="color:#666">1.</span>yaml<span style="color:#bbb">
</span><span style="color:#bbb"></span>pod<span style="color:#bbb"> </span><span style="color:#b44">&#34;private-image-test-1&#34;</span><span style="color:#bbb"> </span>created<span style="color:#bbb">
</span><span style="color:#bbb"></span>$</code></pre></div>
<p>If everything is working, then, after a few moments, you should see:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl logs private-image-test-1
SUCCESS</code></pre></div>
<p>If it failed, then you will see:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl describe pods/private-image-test-1 | grep <span style="color:#b44">&#34;Failed&#34;</span>
  Fri, <span style="color:#666">26</span> Jun <span style="color:#666">2015</span> <span style="color:#666">15</span>:36:13 -0700    Fri, <span style="color:#666">26</span> Jun <span style="color:#666">2015</span> <span style="color:#666">15</span>:39:13 -0700    <span style="color:#666">19</span>    <span style="color:#666">{</span>kubelet node-i2hq<span style="color:#666">}</span>    spec.containers<span style="color:#666">{</span>uses-private-image<span style="color:#666">}</span>    failed        Failed to pull image <span style="color:#b44">&#34;user/privaterepo:v1&#34;</span>: Error: image user/privaterepo:v1 not found</code></pre></div>
<p>You must ensure all nodes in the cluster have the same <code>.docker/config.json</code>.  Otherwise, pods will run on
some nodes and fail to run on others.  For example, if you use node autoscaling, then each instance
template needs to include the <code>.docker/config.json</code> or mount a drive that contains it.</p>

<p>All pods will have read access to images in any private registry once private
registry keys are added to the <code>.docker/config.json</code>.</p>

<h3 id="pre-pulling-images">Pre-pulling Images</h3>

<p><strong>Note:</strong> if you are running on Google Kubernetes Engine, there will already be a <code>.dockercfg</code> on each node with credentials for Google Container Registry.  You cannot use this approach.</p>

<p><strong>Note:</strong> this approach is suitable if you can control node configuration.  It
will not work reliably on GCE, and any other cloud provider that does automatic
node replacement.</p>

<p>By default, the kubelet will try to pull each image from the specified registry.
However, if the <code>imagePullPolicy</code> property of the container is set to <code>IfNotPresent</code> or <code>Never</code>,
then a local image is used (preferentially or exclusively, respectively).</p>

<p>If you want to rely on pre-pulled images as a substitute for registry authentication,
you must ensure all nodes in the cluster have the same pre-pulled images.</p>

<p>This can be used to preload certain images for speed or as an alternative to authenticating to a private registry.</p>

<p>All pods will have read access to any pre-pulled images.</p>

<h3 id="specifying-imagepullsecrets-on-a-pod">Specifying ImagePullSecrets on a Pod</h3>

<p><strong>Note:</strong> This approach is currently the recommended approach for Google Kubernetes Engine, GCE, and any cloud-providers
where node creation is automated.</p>

<p>Kubernetes supports specifying registry keys on a pod.</p>

<h4 id="creating-a-secret-with-a-docker-config">Creating a Secret with a Docker Config</h4>

<p>Run the following command, substituting the appropriate uppercase values:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl create secret docker-registry myregistrykey --docker-server<span style="color:#666">=</span>DOCKER_REGISTRY_SERVER --docker-username<span style="color:#666">=</span>DOCKER_USER --docker-password<span style="color:#666">=</span>DOCKER_PASSWORD --docker-email<span style="color:#666">=</span>DOCKER_EMAIL
secret <span style="color:#b44">&#34;myregistrykey&#34;</span> created.</code></pre></div>
<p>If you need access to multiple registries, you can create one secret for each registry.
Kubelet will merge any <code>imagePullSecrets</code> into a single virtual <code>.docker/config.json</code>
when pulling images for your Pods.</p>

<p>Pods can only reference image pull secrets in their own namespace,
so this process needs to be done one time per namespace.</p>

<h5 id="bypassing-kubectl-create-secrets">Bypassing kubectl create secrets</h5>

<p>If for some reason you need multiple items in a single <code>.docker/config.json</code> or need
control not given by the above command, then you can <a href="../../user-guide/secrets/index.html#creating-a-secret-manually">create a secret using
json or yaml</a>.</p>

<p>Be sure to:</p>

<ul>
<li>set the name of the data item to <code>.dockerconfigjson</code></li>
<li>base64 encode the docker file and paste that string, unbroken
as the value for field <code>data[&quot;.dockerconfigjson&quot;]</code></li>
<li>set <code>type</code> to <code>kubernetes.io/dockerconfigjson</code></li>
</ul>

<p>Example:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">apiVersion:<span style="color:#bbb"> </span>v1<span style="color:#bbb">
</span><span style="color:#bbb"></span>kind:<span style="color:#bbb"> </span>Secret<span style="color:#bbb">
</span><span style="color:#bbb"></span>metadata:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>name:<span style="color:#bbb"> </span>myregistrykey<span style="color:#bbb">
</span><span style="color:#bbb">  </span>namespace:<span style="color:#bbb"> </span>awesomeapps<span style="color:#bbb">
</span><span style="color:#bbb"></span>data:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>.dockerconfigjson:<span style="color:#bbb"> </span>UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==<span style="color:#bbb">
</span><span style="color:#bbb"></span>type:<span style="color:#bbb"> </span>kubernetes.io/dockerconfigjson</code></pre></div>
<p>If you get the error message <code>error: no objects passed to create</code>, it may mean the base64 encoded string is invalid.
If you get an error message like <code>Secret &quot;myregistrykey&quot; is invalid: data[.dockerconfigjson]: invalid value ...</code>, it means
the data was successfully un-base64 encoded, but could not be parsed as a <code>.docker/config.json</code> file.</p>

<h4 id="referring-to-an-imagepullsecrets-on-a-pod">Referring to an imagePullSecrets on a Pod</h4>

<p>Now, you can create pods which reference that secret by adding an <code>imagePullSecrets</code>
section to a pod definition.</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">apiVersion:<span style="color:#bbb"> </span>v1<span style="color:#bbb">
</span><span style="color:#bbb"></span>kind:<span style="color:#bbb"> </span>Pod<span style="color:#bbb">
</span><span style="color:#bbb"></span>metadata:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>name:<span style="color:#bbb"> </span>foo<span style="color:#bbb">
</span><span style="color:#bbb">  </span>namespace:<span style="color:#bbb"> </span>awesomeapps<span style="color:#bbb">
</span><span style="color:#bbb"></span>spec:<span style="color:#bbb">
</span><span style="color:#bbb">  </span>containers:<span style="color:#bbb">
</span><span style="color:#bbb">    </span>-<span style="color:#bbb"> </span>name:<span style="color:#bbb"> </span>foo<span style="color:#bbb">
</span><span style="color:#bbb">      </span>image:<span style="color:#bbb"> </span>janedoe/awesomeapp:v1<span style="color:#bbb">
</span><span style="color:#bbb">  </span>imagePullSecrets:<span style="color:#bbb">
</span><span style="color:#bbb">    </span>-<span style="color:#bbb"> </span>name:<span style="color:#bbb"> </span>myregistrykey</code></pre></div>
<p>This needs to be done for each pod that is using a private registry.</p>

<p>However, setting of this field can be automated by setting the imagePullSecrets
in a <a href="../../user-guide/service-accounts">serviceAccount</a> resource.
Check <a href="../../user-guide/service-accounts#add-imagepullsecrets-to-a-service-account">Add ImagePullSecrets to a Service Account</a> for detailed instructions.</p>

<p>You can use this in conjunction with a per-node <code>.docker/config.json</code>.  The credentials
will be merged.  This approach will work on Google Kubernetes Engine.</p>

<h3 id="use-cases">Use Cases</h3>

<p>There are a number of solutions for configuring private registries.  Here are some
common use cases and suggested solutions.</p>

<ol>
<li>Cluster running only non-proprietary (e.g. open-source) images.  No need to hide images.

<ul>
<li>Use public images on the Docker hub.

<ul>
<li>No configuration required.</li>
<li>On GCE/Google Kubernetes Engine, a local mirror is automatically used for improved speed and availability.</li>
</ul></li>
</ul></li>
<li>Cluster running some proprietary images which should be hidden to those outside the company, but
visible to all cluster users.

<ul>
<li>Use a hosted private <a href="https://docs.docker.com/registry/" target="_blank">Docker registry</a>.

<ul>
<li>It may be hosted on the <a href="https://hub.docker.com/account/signup/" target="_blank">Docker Hub</a>, or elsewhere.</li>
<li>Manually configure .docker/config.json on each node as described above.</li>
</ul></li>
<li>Or, run an internal private registry behind your firewall with open read access.

<ul>
<li>No Kubernetes configuration is required.</li>
</ul></li>
<li>Or, when on GCE/Google Kubernetes Engine, use the project&rsquo;s Google Container Registry.

<ul>
<li>It will work better with cluster autoscaling than manual node configuration.</li>
</ul></li>
<li>Or, on a cluster where changing the node configuration is inconvenient, use <code>imagePullSecrets</code>.</li>
</ul></li>
<li>Cluster with a proprietary images, a few of which require stricter access control.

<ul>
<li>Ensure <a href="../../admin/admission-controllers/index.html#alwayspullimages">AlwaysPullImages admission controller</a> is active. Otherwise, all Pods potentially have access to all images.</li>
<li>Move sensitive data into a &ldquo;Secret&rdquo; resource, instead of packaging it in an image.</li>
</ul></li>
<li>A multi-tenant cluster where each tenant needs own private registry.

<ul>
<li>Ensure <a href="../../admin/admission-controllers/index.html#alwayspullimages">AlwaysPullImages admission controller</a> is active. Otherwise, all Pods of all tenants potentially have access to all images.</li>
<li>Run a private registry with authorization required.</li>
<li>Generate registry credential for each tenant, put into secret, and populate secret to each tenant namespace.</li>
<li>The tenant adds that secret to imagePullSecrets of each namespace.</li>
</ul></li>
</ol>















    
    

				<div class="issue-button-container">
					<p><a href="index.html"><img src="https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/concepts/containers/_index.md?pixel" alt="Analytics" /></a></p>
					
					
					<script type="text/javascript">
					PDRTJS_settings_8345992 = {
					"id" : "8345992",
					"unique_id" : "\/docs\/concepts\/containers\/",
					"title" : "Containers",
					"permalink" : "https:\/\/kubernetes.io\/docs\/concepts\/containers\/"
					};
					(function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/js/rating/rating.js':'http://i0.poll.fm/js/rating/rating.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-rating-js'));
					</script>
					<a href="index.html" onclick="window.open('https://github.com/kubernetes/website/issues/new?title=Issue%20with%20' +
					'k8s.io'+window.location.pathname)" class="button issue">Create an Issue</a>
					
					
					
					<a href="../../editdocs#docs/concepts/containers/_index.md" class="button issue">Edit this Page</a>
					
				</div>
			</div>
		</section>
		<footer>
    <main class="light-text">
        <nav>
            
            
            
            <a href="../../home.1">Documentation</a>
            
            <a href="../../../blog/index.html">Blog</a>
            
            <a href="../../../partners/index.html">Partners</a>
            
            <a href="../../../community/index.html">Community</a>
            
            <a href="../../../case-studies/index.html">Case Studies</a>
            
        </nav>
        <div class="social">
            <div>
                <a href="https://twitter.com/kubernetesio" class="twitter"><span>twitter</span></a>
                <a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
                <a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
            </div>
            <div>
                <a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>Stack Overflow</span></a>
                <a href="https://discuss.kubernetes.io" class="mailing-list"><span>Forum</span></a>
                <a href="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com" class="calendar"><span>Events Calendar</span></a>
            </div>
            <div>
                <a href="../../getting-started-guides/index.html" class="button">Get Kubernetes</a>
                <a href="https://git.k8s.io/community/contributors/guide" class="button">Contribute</a>
            </div>
        </div>
        <div id="miceType" class="center">
            &copy; 2018 The Kubernetes Authors | Documentation Distributed under <a href="https://git.k8s.io/website/LICENSE" class="light-text">CC BY 4.0</a>
        </div>
        <div id="miceType" class="center">
            Copyright &copy; 2018 The Linux Foundation&reg;. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our <a href="https://www.linuxfoundation.org/trademark-usage" class="light-text">Trademark Usage page</a>
        </div>
    </main>
</footer>

		<button class="flyout-button" onclick="kub.toggleToc()"></button>

<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-36037335-10', 'auto');
ga('send', 'pageview');


(function () {
    window.addEventListener('DOMContentLoaded', init)

        
        function init() {
            window.removeEventListener('DOMContentLoaded', init)
                hideNav()
        }

    function hideNav(toc){
        if (!toc) toc = document.querySelector('#docsToc')
        if (!toc) return
            var container = toc.querySelector('.container')

                
                if (container) {
                    if (container.childElementCount === 0 || toc.querySelectorAll('a.item').length === 1) {
                        toc.style.display = 'none'
                            document.getElementById('docsContent').style.width = '100%'
                    }
                } else {
                    requestAnimationFrame(function () {
                        hideNav(toc)
                    })
                }
    }
})();
</script>



	</body>
</html>